package com.jrx.anytxn.investor.service.impl;

import com.jrx.anytxn.common.constant.CommonContants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.exception.TxnRuntimeException;
import com.jrx.anytxn.common.uitl.*;
import com.jrx.anytxn.investor.bean.InvestorCastAccountBean;
import com.jrx.anytxn.investor.bean.InvestorCastAccountTransactionBean;
import com.jrx.anytxn.investor.constant.TransBizConstant;
import com.jrx.anytxn.investor.dto.loan.LoanReq;
import com.jrx.anytxn.investor.entity.*;
import com.jrx.anytxn.investor.service.IInvestorAccountService;
import com.jrx.anytxn.investor.service.IInvestorGlInterfaceService;
import com.jrx.anytxn.investor.service.IInvestorRepaymentPlanService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.param.dto.system.SystemParameterRes;
import com.jrx.anytxn.param.entity.*;
import com.jrx.anytxn.param.service.investor.IPrInvestorInterestRateService;
import com.jrx.anytxn.param.service.investor.IPrInvestorPenaltyRateService;
import com.jrx.anytxn.param.service.product.IAmortMethodService;
import com.jrx.anytxn.param.service.product.IProductTableService;
import com.jrx.anytxn.param.service.system.ISystemParameterService;
import com.jrx.anytxn.transaction.bean.DelqNonAccrualBean;
import com.jrx.anytxn.transaction.bean.DelqParamBean;
import com.jrx.anytxn.transaction.entity.AmLoanMainInfo;
import com.jrx.anytxn.transaction.service.IDealDelqService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 联合贷账户Service理接口实现
 *
 * @author liuyang
 * @date 2020-05-18
 */
@Service
public class InvestorAccountServiceImpl implements IInvestorAccountService {

    private static final Logger logger = LoggerFactory.getLogger(InvestorAccountServiceImpl.class);

    @Autowired
    private ISystemParameterService systemParameterService;

    @Autowired
    private IPrInvestorInterestRateService investorInterestRateService;

    @Autowired
    private IInvestorRepaymentPlanService repaymentPlanInvestorService;

    @Autowired
    private ISegmentService segmentService;

    @Autowired
    private IAmortMethodService amortMethodService;


    @Autowired
    private IInvestorGlInterfaceService glInterfaceInvestorService;

    @Autowired
    private IDealDelqService delqService;

    @Autowired
    private InvestorRepaymentPlanServiceImpl repaymentPlanService;


    @Autowired
    private IProductTableService productTableService;

    @Autowired
    private IPrInvestorPenaltyRateService prInvestorPenaltyRateService;

    /**
     * 构建贷款信息
     *
     * @param loanMainInfo 对客订单
     * @param loanReq 放款请求信息
     * @param fundFactor 出资方信息
     * @param loanAmount 贷款金额
     * @return AmLoanMainInvestorInfo 贷款信息
     * @throws TxnException
     * @author liuyang
     * @date 2020-05-18
     */
    @Override
    public AmLoanMainInvestorInfo buildAmLoanMainInvestorInfo(AmLoanMainInfo loanMainInfo, LoanReq loanReq, PrFundFactor fundFactor, BigDecimal loanAmount) throws TxnException {

        //获取贷款基础利率
        SystemParameterRes loanPrimeRateRes = systemParameterService.findByParamCode(TransBizConstant.LOAN_PRIME_RATE,loanReq.getTenantId());

        // 获取利息信息
        PrInvestorInterestRate interest = investorInterestRateService.findInterestByInterestId(loanReq.getInvestorInterestTableId(), loanMainInfo.getOrganizationId(),loanReq.getTenantId());
        BigDecimal dayRate = investorInterestRateService.getDailyRate(interest, loanReq.getBusinessDate()); //日利率
        BigDecimal yearRate = investorInterestRateService.getYearRate(interest); //年利率

        // 构建贷款信息
        AmLoanMainInvestorInfo loanMainInvestorInfo = new  AmLoanMainInvestorInfo();
        BeanMapping.copy(loanMainInfo,loanMainInvestorInfo); // 复制对客订单信息
        try {
            loanMainInvestorInfo.setId(segmentService.getId(TransBizConstant.AM_LOAN_MAIN_INVESTOR_INFO)); // 主键id
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        loanMainInvestorInfo.setInvestorLoanId(this.getLoanId(loanReq.getTenantId(),loanReq.getCustomerId())); // 出资方贷款订单id	根据贷款订单id生成策略得出
        loanMainInvestorInfo.setInvestorId(fundFactor.getInvestorId()); // 出资方ID
        loanMainInvestorInfo.setInvertorPercentage(fundFactor.getInvertorPercentage()); // 出资方比例
        loanMainInvestorInfo.setTxnCode(TransBizConstant.TXN_CODE_INSTSUM); // 交易码	50099 分期总额交易
        loanMainInvestorInfo.setLoanAmount(loanAmount); // 贷款金额	对客金额*出资比例
        loanMainInvestorInfo.setLoanPrimeRate(StringUtils.isNotBlank(loanPrimeRateRes.getParamValue())?new BigDecimal(loanPrimeRateRes.getParamValue()):BigDecimal.ZERO); // LPR贷款基础利率
        loanMainInvestorInfo.setInterestRate(yearRate); // 年利率
        loanMainInvestorInfo.setActualDailyRate(dayRate); // 执行日利率
        loanMainInvestorInfo.setInvestorInterestTableId(loanReq.getInvestorInterestTableId()); // 利息参数表id
        loanMainInvestorInfo.setInvestorPayoffTableId(loanReq.getInvestorPayoffTableId()); // 提前结清参数表id
        loanMainInvestorInfo.setInvestorPenaltyTableId(loanReq.getInvestorPenaltyTableId()); // 罚息参数表id
        loanMainInvestorInfo.setInvestorFeeTableId(loanReq.getInvestorFeeTableId()); // 费用参数表id
        loanMainInvestorInfo.setInvestorPrepayTableId(loanReq.getInvestorPrepayTableId()); // 提前还款参数表id
        loanMainInvestorInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER); // 记录版本号	初始固定值：1
        loanMainInvestorInfo.setOffsetFlag(fundFactor.getOffsetFlag());//轧差标志
        loanMainInvestorInfo.setCreateTime(null); // 创建时间设置为空
        loanMainInvestorInfo.setUpdateTime(null); // 更新时间设置为空
        return loanMainInvestorInfo;
    }

    /**
     * 构建贷款账户
     *
     * @param loanMainInvestorInfo 贷款信息
     * @return AmLoanAccountInvestorInfo 贷款账户
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-19
     */
    @Override
    public AmLoanAccountInvestorInfo buildAmLoanAccountInvestorInfo(AmLoanMainInvestorInfo loanMainInvestorInfo) throws TxnBizException {
        // 构建贷款账户
        AmLoanAccountInvestorInfo loanAccountInvestorInfo = new AmLoanAccountInvestorInfo();
        BeanMapping.copy(loanMainInvestorInfo,loanAccountInvestorInfo); // 复制订单信息
        try {
            loanMainInvestorInfo.setId(segmentService.getId(TransBizConstant.AM_LOAN_ACCOUNT_INVESTOR_INFO)); // 主键id
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        loanAccountInvestorInfo.setAccountStatus(TransBizConstant.LOAN_STATUS_0); // 贷款状态	0 = 新建
        loanAccountInvestorInfo.setCurrBalance(BigDecimal.ZERO); // 余额
        loanAccountInvestorInfo.setPrincipalBalance(BigDecimal.ZERO); // 本金余额
        loanAccountInvestorInfo.setInterestBalance(BigDecimal.ZERO); // 利息余额
        loanAccountInvestorInfo.setPenaltyBalance(BigDecimal.ZERO); // 罚息余额
        loanAccountInvestorInfo.setCompoundBalance(BigDecimal.ZERO); // 复利余额
        loanAccountInvestorInfo.setFeeBalance(BigDecimal.ZERO); // 服务费余额
        loanAccountInvestorInfo.setRemainPrincipal(loanMainInvestorInfo.getLoanAmount()); // 剩余本金
        loanAccountInvestorInfo.setAccruedInterest(BigDecimal.ZERO); // 计提利息
        loanAccountInvestorInfo.setAccruedPenalty(BigDecimal.ZERO); // 计提罚息
        loanAccountInvestorInfo.setAccruedCompound(BigDecimal.ZERO); // 计提复利
        loanAccountInvestorInfo.setCastTenor(TransBizConstant.ZERO); // 已抛期数
        loanAccountInvestorInfo.setPayedTenor(TransBizConstant.ZERO); // 已还期数
        loanAccountInvestorInfo.setChargeoffFlag(TransBizConstant.NO_FLAG); // 核销标志 0 = 否
        loanAccountInvestorInfo.setWaiveInterestFlag(TransBizConstant.YES_FLAG); // 停息标志 1 = 正常计息
        loanAccountInvestorInfo.setWaiveFeeFlag(TransBizConstant.YES_FLAG); // 停费标志 1 = 正常计费
        loanAccountInvestorInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG); // 代偿标识 订单是否已代偿，默认0=否
        loanAccountInvestorInfo.setBalTransferFlag(TransBizConstant.NO_FLAG); // 债权转移标识 订单是否已债权转移，默认0=否
        loanAccountInvestorInfo.setTotalCompensatoryTenor(TransBizConstant.ZERO); // 总代偿期数
        loanAccountInvestorInfo.setContinueOverDueTenor(TransBizConstant.ZERO); // 连续逾期期数
        loanAccountInvestorInfo.setTotalOverDueTenor(TransBizConstant.ZERO); // 总逾期期数
        loanAccountInvestorInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0); // 会计状态 0 = 正常
        loanAccountInvestorInfo.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0); // 非应计状态	0 = 应计
        loanAccountInvestorInfo.setDelqDays(TransBizConstant.ZERO); // 当前延滞天数
        loanAccountInvestorInfo.setLoanClassify(TransBizConstant.LOAN_CLASSIFY_0); // 五级分类	0 = 正常
        loanAccountInvestorInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER); // 记录版本号
        loanAccountInvestorInfo.setCreateTime(null); // 创建时间设置为空
        loanAccountInvestorInfo.setUpdateTime(null); // 更新时间设置为空
        return loanAccountInvestorInfo;
    }

    /**
     * 获取订单id
     *
     * @param tenantId 租户id
     * @param customerId 客户id
     * @return loanId 订单id
     * @author liuyang
     * @date 2020-05-18
     */
    private String getLoanId(String tenantId,String customerId){
        StringBuilder stringBuilder = new StringBuilder();
        //取客户后2位
        String customerSuffix = StringUtils.right(customerId,TransBizConstant.LOAN_ID_CUSTOMER_PLACE);
        //accountType(2位)+tenant_id(4位)+customer_id后2位+yyyyMMddHHmmssSSS(17位)+7位随机
        stringBuilder.append(tenantId).append(customerSuffix).append(SeqUtils.getSNByLength(TransBizConstant.LOAN_ID_RANDOM_PLACE));
        return stringBuilder.toString();
    }

    /**
     * 根据还款计划更新贷款信息和贷款账户信息
     *
     * @param loanMainInvestorInfo 贷款信息
     * @param loanAccountInvestorInfo 贷款账户
     * @param repaymentPlanInvestorInfos 还款计划
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-20
     */
    @Override
    public void updateLoanMainAndAccountInvestorInfo(AmLoanMainInvestorInfo loanMainInvestorInfo, AmLoanAccountInvestorInfo loanAccountInvestorInfo,List<AmRepaymentPlanInvestorInfo> repaymentPlanInvestorInfos) throws TxnException {
        loanMainInvestorInfo.setFirstPaymentDate(repaymentPlanInvestorInfos.get(0).getPaymentDueDate()); //首期还款日
        loanMainInvestorInfo.setLastPaymentDate(repaymentPlanInvestorInfos.get(repaymentPlanInvestorInfos.size() - 1).getPaymentDueDate()); //最后还款日
        //计算下次还款日
        Date nextPaymentDay = repaymentPlanInvestorInfos.size() == 1 ? loanMainInvestorInfo.getFirstPaymentDate() : repaymentPlanInvestorInfos.get(1).getPaymentDueDate();
        loanAccountInvestorInfo.setNextPaymentDate(nextPaymentDay); //设置下次还款日期
        //若利随本清重新赋值订单还款日
        PrAmortMethod amortMethod = amortMethodService.findByChargerOptionAndId(loanMainInvestorInfo.getAmortMethodTableId(),loanMainInvestorInfo.getOrganizationId(),loanMainInvestorInfo.getTenantId());
        if (TransBizConstant.PRIN_CHARGE_OPTION_INTPAY.equals(amortMethod.getChargeOption())) {
            loanMainInvestorInfo.setBillingCycle(Integer.parseInt(DateUtils.getDay(nextPaymentDay)));
        }
        int totalDays = DateUtils.getDaysBetween(loanMainInvestorInfo.getPostingDate(), loanMainInvestorInfo.getLastPaymentDate());
        loanMainInvestorInfo.setTotalDays(totalDays);// 总天数
    }

    /**
     * 抛账  抛分期费用账户
     *
     * @param loanMainInvestorInfo 贷款信息
     * @param loanAccountInvestorInfo 贷款账户
     * @param repaymentPlanInvestorInfo 还款计划
     * @param businessDate 业务日期
     * @return InvestorCastAccountTransactionBean 费用交易账户
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-20
     */
    @Override
    public InvestorCastAccountTransactionBean castInstallmentFeeAccount(AmLoanMainInvestorInfo loanMainInvestorInfo, AmLoanAccountInvestorInfo loanAccountInvestorInfo, AmRepaymentPlanInvestorInfo repaymentPlanInvestorInfo, Date businessDate) throws TxnException {

        if (repaymentPlanInvestorInfo.getFeeAmount() == null || repaymentPlanInvestorInfo.getFeeAmount().compareTo(BigDecimal.ZERO) == 0) {
            return null;
        }
        AmAccountMainInvestorInfo feeAccount = new AmAccountMainInvestorInfo();
        BeanMapping.copy(loanMainInvestorInfo, feeAccount);
        try {
            feeAccount.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_MAIN_INVESTOR_INFO));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        feeAccount.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_03, loanMainInvestorInfo.getTenantId(), loanMainInvestorInfo.getCustomerId()));//账户ID
        feeAccount.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        feeAccount.setAccountType(TransBizConstant.ACCOUNT_TYPE_03);//账户类型
        feeAccount.setTxnCode(TransBizConstant.TXN_CODE_INST_FEE);//交易码
        feeAccount.setPostingAmount(repaymentPlanInvestorInfo.getFeeAmount());//入账金额
        feeAccount.setPostingDate(businessDate);//入账时间
        feeAccount.setRepayAmount(BigDecimal.ZERO);//已还金额
        feeAccount.setBillingTenor(repaymentPlanInvestorInfo.getBillingTenor());//期次
        feeAccount.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        feeAccount.setCurrBalance(repaymentPlanInvestorInfo.getFeeAmount());//余额
        feeAccount.setInterestStartDate(businessDate);//交易起息日
        feeAccount.setPaymentDueDate(repaymentPlanInvestorInfo.getPaymentDueDate());//到期还款日
        feeAccount.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        feeAccount.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        feeAccount.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        feeAccount.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        feeAccount.setLiabilityFlag(repaymentPlanInvestorInfo.getLiabilityFlag());
        feeAccount.setTaxAmt(BigDecimal.ZERO);
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setUpdateBy(TransBizConstant.SYS_OPRATE);
        feeAccount.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);//会计状态
        feeAccount.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);//应计/非应计
        feeAccount.setLoanClassify(loanAccountInvestorInfo.getLoanClassify());//五级分类
        feeAccount.setCreateTime(null); // 创建时间设置为空
        feeAccount.setUpdateTime(null); // 更新时间设置为空
        //更新订单上的余额  上层需更新订单 将更新字段入库
        loanAccountInvestorInfo.setCurrBalance(loanAccountInvestorInfo.getCurrBalance().add(feeAccount.getPostingAmount()));
        loanAccountInvestorInfo.setFeeBalance(loanAccountInvestorInfo.getFeeBalance().add(feeAccount.getPostingAmount()));
        //生成GL流水
        TlGlInterfaceInvestorInfo tlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(feeAccount, feeAccount.getPostingAmount(), feeAccount.getTxnCode(), feeAccount.getAccountingPhase(), businessDate);
        InvestorCastAccountTransactionBean castAccountTransactionBean = new InvestorCastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(feeAccount);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    /**
     * 生成账户id
     *
     * @param accountType 账户类型
     * @param tenantId 租户id
     * @param customerId 客户id
     * @return String 账户id
     * @author liuyang
     * @date 2020-05-20
     */
    @Override
    public String getAccountId(String accountType, String tenantId, String customerId) {
        StringBuilder stringBuilder = new StringBuilder();
        //取客户后2位
        String customerSuffix = StringUtils.right(customerId, TransBizConstant.ACCOUNT_ID_CUSTOMER_PLACE);
        //accountType(2位)+tenant_id(4位)+customer_id后2位+yyyyMMddHHmmssSSS(17位)+7位随机
        stringBuilder.append(accountType).append(tenantId).append(customerSuffix).append(SeqUtils.getSNByLength(TransBizConstant.ACCOUNT_ID_RANDOM_PLACE));
        return stringBuilder.toString();
    }

    /**
     * 抛账  抛出利息累计账户
     *
     * @param repaymentPlanInvestorInfo 还款计划
     * @param accountMainInvestorInfo 交易账户信息
     * @param loanAccountInvestorInfo 订单账户
     * @param loanMainInvestorInfo 订单信息
     * @param accrualBaseAmount 计息金额
     * @param delqParamBean 延滞参数
     * @return AmInterestAccrualInvestorInfo 利息累计账户
     * @throws TxnException
     * @author liuyang
     * @date 2020-05-21
     */
    @Override
    public AmInterestAccrualInvestorInfo castInterestAccrualAccount(AmRepaymentPlanInvestorInfo repaymentPlanInvestorInfo, AmAccountMainInvestorInfo accountMainInvestorInfo, AmLoanAccountInvestorInfo loanAccountInvestorInfo, AmLoanMainInvestorInfo loanMainInvestorInfo, BigDecimal accrualBaseAmount, DelqParamBean delqParamBean) throws TxnException {

        if(BigDecimal.ZERO.compareTo(repaymentPlanInvestorInfo.getInterestAmount())>=0){
            return null;
        }

        AmInterestAccrualInvestorInfo amInterestAccrualInfo = new AmInterestAccrualInvestorInfo();
        BeanMapping.copy(accountMainInvestorInfo, amInterestAccrualInfo);
        try {
            amInterestAccrualInfo.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INVESTOR_INFO));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        amInterestAccrualInfo.setAccountId(getAccountId(TransBizConstant.INTEREST_ACCRUAL_TYPE_66, accountMainInvestorInfo.getTenantId(), accountMainInvestorInfo.getCustomerId()));//账户ID
        amInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_1);//状态
        amInterestAccrualInfo.setAccountType(TransBizConstant.INTEREST_ACCRUAL_TYPE_66);//类型 利息累计账户
        amInterestAccrualInfo.setAccrualBaseAmount(accrualBaseAmount);//计息金额
        amInterestAccrualInfo.setAccrualStartDate(repaymentPlanInvestorInfo.getIntrStartDate());//交易起息日期
        amInterestAccrualInfo.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        amInterestAccrualInfo.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        amInterestAccrualInfo.setAccrualDailyRate(loanMainInvestorInfo.getActualDailyRate());//实际日利率
        amInterestAccrualInfo.setAccrualNewFromDate(DateUtils.addDay(repaymentPlanInvestorInfo.getIntrStartDate(), -1));//累计利息开始日期
        amInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_0);//停止累计息标志	0 = 正常计息  1 = 停止计息
        amInterestAccrualInfo.setMaxInterest(repaymentPlanInvestorInfo.getInterestAmount());//最大利息金额
        amInterestAccrualInfo.setProfitShared(TransBizConstant.NO_FLAG);//是否已经分润	0 = 未分润 1 = 已分润  默认为0，未分润	初始固定值：0
        amInterestAccrualInfo.setBalTransferFlag(TransBizConstant.NO_FLAG);//债权转移标识
        amInterestAccrualInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG);//代偿标识
        amInterestAccrualInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);//	记录版本号	初始固定值：1
        amInterestAccrualInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amInterestAccrualInfo.setTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setLiabilityFlag(repaymentPlanInvestorInfo.getLiabilityFlag());
        amInterestAccrualInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);//会计状态
        amInterestAccrualInfo.setCreateTime(null); // 创建时间设置为空
        amInterestAccrualInfo.setUpdateTime(null); // 更新时间设置为空
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amInterestAccrualInfo, loanAccountInvestorInfo);
        //五级分类
        amInterestAccrualInfo.setLoanClassify(loanAccountInvestorInfo.getLoanClassify());
        amInterestAccrualInfo.setInterestTableId(loanMainInvestorInfo.getInvestorInterestTableId()); // 利率参数id
        amInterestAccrualInfo.setPenaltyTableId(loanMainInvestorInfo.getInvestorPenaltyTableId()); // 罚息参数id
        if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
            amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR_ACCU);
        } else {
            amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR_NONACCRUAL_ACCU);
        }
        return amInterestAccrualInfo;
    }

    /**
     * 获取订单计划剩余本金金额
     *
     * @param repaymentPlanInfoList 还款计划
     * @param billingTenor 第几期
     * @return BigDecimal 剩余本金
     * @author liuyang
     * @date 2020-05-20
     */
    @Override
    public BigDecimal getPlanPrinBalance(List<AmRepaymentPlanInvestorInfo> repaymentPlanInfoList, Integer billingTenor) {
        BigDecimal prinBalance = BigDecimal.ZERO;
        for (AmRepaymentPlanInvestorInfo repaymentPlanInfo : repaymentPlanInfoList) {
            if (repaymentPlanInfo.getBillingTenor() >= billingTenor) {
                prinBalance = prinBalance.add(repaymentPlanInfo.getPrincipalAmount()).subtract(repaymentPlanInfo.getRepayPrincipal());
            }
        }
        return prinBalance;
    }

    /**
     * 抛账   抛当期本金、费用、利息累计
     *
     * @param loanMainInvestorInfo 订单信息
     * @param loanAccountInvestorInfo 订单账户
     * @param repaymentPlanInfoList 还款计划
     * @param businessDate 业务日期
     * @param isValid 是否需要验证今天是否是抛账日
     * @return InvestorCastAccountBean 抛账更新的信息
     * @throws TxnException
     * @author liuyang
     * @date 2020-05-21
     */
    @Override
    public InvestorCastAccountBean castTxnAccount(AmLoanMainInvestorInfo loanMainInvestorInfo, AmLoanAccountInvestorInfo loanAccountInvestorInfo, List<AmRepaymentPlanInvestorInfo> repaymentPlanInfoList, Date businessDate, Boolean isValid) throws TxnException{
        if (loanMainInvestorInfo == null) {
            return null;
        }
        logger.debug("开始抛帐出资方的贷款id:{}", loanMainInvestorInfo.getInvestorLoanId());
        if (loanAccountInvestorInfo.getCastTenor() >= loanMainInvestorInfo.getTotalTenor()) {//如果订单已抛期数等于订单总期数，返回
            return null;
        }

        //获取订单属性值
        Integer billingTenor = loanAccountInvestorInfo.getCastTenor() + 1;
        if(billingTenor > loanMainInvestorInfo.getTotalTenor()){
            //尾期已抛帐
            return null;
        }

        AmRepaymentPlanInvestorInfo prePlan = this.getRepaymentPlanInfo(loanAccountInvestorInfo.getCastTenor(), repaymentPlanInfoList);

        if (isValid) {
            //是否验证今天是抛账日
            if (prePlan != null && prePlan.getPaymentDueDate().compareTo(businessDate) != 0) {
                return null;
            }
        }

        AmRepaymentPlanInvestorInfo currPlan = this.getRepaymentPlanInfo(billingTenor, repaymentPlanInfoList);
        if (currPlan == null) {
            logger.error("出资方贷款id：{} 当前期[{}]计划为空", loanMainInvestorInfo.getInvestorLoanId(), billingTenor);
            throw new TxnRuntimeException("获取当期还款计划失败");
        }

        InvestorCastAccountBean investorCastAccountBean = new InvestorCastAccountBean();

        logger.debug("是抛帐日，开始生成本利费交易账户出资方贷款id:{}", loanMainInvestorInfo.getInvestorLoanId());

        DelqParamBean delqParamBean = delqService.buildDqlqAccountBean(loanMainInvestorInfo.getTenantId(),loanMainInvestorInfo.getDelqTableId());

        //抛账  本金账户
        InvestorCastAccountTransactionBean castPrincipalAccount = castPrincipalAccount(loanMainInvestorInfo, loanAccountInvestorInfo, currPlan,delqParamBean, businessDate);
        investorCastAccountBean.addAccountMainInfo(castPrincipalAccount.getAmAccountMainInfo());
        investorCastAccountBean.addAllTlGlInterfaceInfo(castPrincipalAccount.getTlGlInterfaceInfoList());

        // 计算计息金额
        BigDecimal accrualBaseAmount = null;
        PrInvestorInterestRate interestRate = investorInterestRateService.findInterestByInterestId(loanMainInvestorInfo.getInvestorInterestTableId(),loanMainInvestorInfo.getOrganizationId(),loanMainInvestorInfo.getTenantId());
        if (interestRate == null) {
            logger.error("获取利率参数{}失败", loanMainInvestorInfo.getInvestorInterestTableId());
            throw new TxnRuntimeException("获取利率参数" + loanMainInvestorInfo.getInvestorInterestTableId() + "失败");
        }
        String accrualBasic = interestRate.getAccrualBasic();//计息基础  0 = 剩余本金   1 = 贷款本金
        if (TransBizConstant.ACCRUAL_BASIC_0.equals(accrualBasic)) {
            accrualBaseAmount = this.getPlanPrinBalance(repaymentPlanInfoList, billingTenor);
        } else if (TransBizConstant.ACCRUAL_BASIC_1.equals(accrualBasic)) {
            accrualBaseAmount = loanMainInvestorInfo.getLoanAmount();
        }

        //生成利息累计
        AmInterestAccrualInvestorInfo amInterestAccrualInfo = castInterestAccrualAccount(currPlan,
                castPrincipalAccount.getAmAccountMainInfo(), loanAccountInvestorInfo, loanMainInvestorInfo, accrualBaseAmount, delqParamBean);
        investorCastAccountBean.addInterestAccrualInfo(amInterestAccrualInfo);


        //生成分期费用账户
        InvestorCastAccountTransactionBean castInstallmentFeeAccount = null;
        if (StringUtils.isNotBlank(loanMainInvestorInfo.getInvestorFeeTableId())) {
            castInstallmentFeeAccount = castInstallmentFeeAccount(loanMainInvestorInfo, loanAccountInvestorInfo, currPlan, businessDate);
        }
        if (castInstallmentFeeAccount != null) {
            investorCastAccountBean.addAccountMainInfo(castInstallmentFeeAccount.getAmAccountMainInfo());
            investorCastAccountBean.addAllTlGlInterfaceInfo(castInstallmentFeeAccount.getTlGlInterfaceInfoList());
        }

        //更新订单信息
        AmLoanAccountInvestorInfo updateLoanAccount = new AmLoanAccountInvestorInfo();
        updateLoanAccount.setId(loanAccountInvestorInfo.getId());
        updateLoanAccount.setCustomerId(loanAccountInvestorInfo.getCustomerId());
        updateLoanAccount.setTenantId(loanAccountInvestorInfo.getTenantId());
        updateLoanAccount.setOrganizationId(loanAccountInvestorInfo.getOrganizationId());
        if (loanAccountInvestorInfo.getCastTenor() == 0 && TransBizConstant.LOAN_STATUS_0.equals(loanAccountInvestorInfo.getAccountStatus())) {
            updateLoanAccount.setAccountStatus(TransBizConstant.LOAN_STATUS_1);
            loanAccountInvestorInfo.setAccountStatus(TransBizConstant.LOAN_STATUS_1);
        }
        updateLoanAccount.setCastTenor(billingTenor);
        loanAccountInvestorInfo.setCastTenor(billingTenor);
        updateLoanAccount.setCurrBalance(loanAccountInvestorInfo.getCurrBalance());
        updateLoanAccount.setPrincipalBalance(loanAccountInvestorInfo.getPrincipalBalance());
        updateLoanAccount.setFeeBalance(loanAccountInvestorInfo.getFeeBalance());
        updateLoanAccount.setNextPaymentDate(currPlan.getPaymentDueDate());
        loanAccountInvestorInfo.setNextPaymentDate(currPlan.getPaymentDueDate());
        investorCastAccountBean.addUpdateLoanAccount(updateLoanAccount);

        //更新还款计划
        AmRepaymentPlanInvestorInfo updateCurrPlan = new AmRepaymentPlanInvestorInfo();
        updateCurrPlan.setId(currPlan.getId());
        updateCurrPlan.setCustomerId(currPlan.getCustomerId());
        updateCurrPlan.setTenantId(currPlan.getTenantId());
        updateCurrPlan.setOrganizationId(currPlan.getOrganizationId());

        updateCurrPlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_1);
        currPlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_1);
        investorCastAccountBean.addUpdateRepaymentPlan(updateCurrPlan);

        logger.debug("抛帐结束InvestorLoanId:{}", loanMainInvestorInfo.getInvestorLoanId());
        return investorCastAccountBean;
    }

    /**
     * 得到当期还款计划明细
     *
     * @param tenor 第几期
     * @param repaymentPlanInfoList 还款计划列表
     * @return AmRepaymentPlanInvestorInfo 还款计划
     * @author liuyang
     * @date 2020-05-21
     */
    @Override
    public AmRepaymentPlanInvestorInfo getRepaymentPlanInfo(Integer tenor, List<AmRepaymentPlanInvestorInfo> repaymentPlanInfoList) {
        AmRepaymentPlanInvestorInfo curr = null;
        if (tenor == null) {
            return null;
        }
        for (AmRepaymentPlanInvestorInfo tmp : repaymentPlanInfoList) {
            if (Objects.equals(tenor, tmp.getBillingTenor())) {
                curr = tmp;
                break;
            }
        }
        return curr;
    }

    /**
     * 抛账  抛出本金账户
     *
     * @param loanMainInvestorInfo 订单信息
     * @param loanAccountInvestorInfo 订单账户
     * @param repaymentPlanInfo 还款计划
     * @param delqParamBean 延滞参数
     * @param businessDate 业务日期
     * @return InvestorCastAccountTransactionBean 账户交易信息
     * @throws TxnException
     * @author liuyang
     * @date 2020-05-21
     */
    @Override
    public InvestorCastAccountTransactionBean castPrincipalAccount(AmLoanMainInvestorInfo loanMainInvestorInfo, AmLoanAccountInvestorInfo loanAccountInvestorInfo, AmRepaymentPlanInvestorInfo repaymentPlanInfo, DelqParamBean delqParamBean, Date businessDate) throws TxnException{
        AmAccountMainInvestorInfo accountMainInvestorInfo = new AmAccountMainInvestorInfo();
        BeanMapping.copy(loanMainInvestorInfo, accountMainInvestorInfo);
        try {
            accountMainInvestorInfo.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_MAIN_INVESTOR_INFO));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        accountMainInvestorInfo.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_06, accountMainInvestorInfo.getTenantId(), loanMainInvestorInfo.getCustomerId()));//账户ID
        accountMainInvestorInfo.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        accountMainInvestorInfo.setAccountType(TransBizConstant.ACCOUNT_TYPE_06);//账户类型
        accountMainInvestorInfo.setTxnCode(TransBizConstant.TXN_CODE_INST);//交易码
        accountMainInvestorInfo.setBillingTenor(repaymentPlanInfo.getBillingTenor());//第几期	　
        accountMainInvestorInfo.setPostingAmount(repaymentPlanInfo.getPrincipalAmount());//入账金额
        accountMainInvestorInfo.setPostingDate(businessDate);//入账时间
        accountMainInvestorInfo.setRepayAmount(BigDecimal.ZERO);//已还金额
        accountMainInvestorInfo.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        accountMainInvestorInfo.setCurrBalance(repaymentPlanInfo.getPrincipalAmount());//余额
        accountMainInvestorInfo.setInterestStartDate(businessDate);//交易起息日
        accountMainInvestorInfo.setPaymentDueDate(repaymentPlanInfo.getPaymentDueDate());//到期还款日
        accountMainInvestorInfo.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        accountMainInvestorInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        accountMainInvestorInfo.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        accountMainInvestorInfo.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        accountMainInvestorInfo.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        accountMainInvestorInfo.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        accountMainInvestorInfo.setLiabilityFlag(repaymentPlanInfo.getLiabilityFlag());
        accountMainInvestorInfo.setTaxAmt(BigDecimal.ZERO);
        accountMainInvestorInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        if(TransBizConstant.COMPENSATORY_FLAG_1.equals(loanAccountInvestorInfo.getCompensatoryFlag())){
            accountMainInvestorInfo.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_1);
            accountMainInvestorInfo.setCompensatoryDays(1);
        }
        accountMainInvestorInfo.setAccountingPhase(loanAccountInvestorInfo.getAccountingPhase());//会计标志
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, accountMainInvestorInfo, loanAccountInvestorInfo);
        accountMainInvestorInfo.setLoanClassify(loanAccountInvestorInfo.getLoanClassify());//五级分类
        accountMainInvestorInfo.setCreateTime(null); // 创建时间设置为空
        accountMainInvestorInfo.setUpdateTime(null); // 更新时间设置为空

        //更新订单上的余额  上层需更新订单 将更新字段入库
        loanAccountInvestorInfo.setCurrBalance(loanAccountInvestorInfo.getCurrBalance().add(accountMainInvestorInfo.getPostingAmount()));
        loanAccountInvestorInfo.setPrincipalBalance(loanAccountInvestorInfo.getPrincipalBalance().add(accountMainInvestorInfo.getPostingAmount()));

        //生成Gl流水
        TlGlInterfaceInvestorInfo tlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(accountMainInvestorInfo, accountMainInvestorInfo.getPostingAmount(),
                accountMainInvestorInfo.getTxnCode(), accountMainInvestorInfo.getAccountingPhase(), businessDate);
        InvestorCastAccountTransactionBean castAccountTransactionBean = new InvestorCastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(accountMainInvestorInfo);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);

        return castAccountTransactionBean;
    }

    /**
     * 累计账户抛账  抛出交易账户
     * @param loanMainInvestorInfo
     * @param loanAccountInvestorInfo
     * @param amInterestAccrualInvestorInfo
     * @param businessDate
     * @return
     * @throws TxnException
     */
    @Override
    public InvestorCastAccountTransactionBean castInterestAccount(AmLoanMainInvestorInfo loanMainInvestorInfo, AmLoanAccountInvestorInfo loanAccountInvestorInfo, AmInterestAccrualInvestorInfo amInterestAccrualInvestorInfo, Date businessDate) throws TxnException {
        AmAccountMainInvestorInfo intrAcct = new AmAccountMainInvestorInfo();
        BeanMapping.copy(loanMainInvestorInfo, intrAcct);
        try {
            intrAcct.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_MAIN_INVESTOR_INFO));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }

        intrAcct.setPostingAmount(amInterestAccrualInvestorInfo.getAccrualTotalAccruInterest());//入账金额
        intrAcct.setCurrBalance(amInterestAccrualInvestorInfo.getAccrualTotalAccruInterest());//余额
        intrAcct.setRepayAmount(BigDecimal.ZERO);//已还金额
        intrAcct.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        intrAcct.setPaymentDueDate(amInterestAccrualInvestorInfo.getPaymentDueDate());//到期还款日
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setOriginalAccountId(amInterestAccrualInvestorInfo.getAccountId());
        intrAcct.setBillingTenor(amInterestAccrualInvestorInfo.getBillingTenor());
        intrAcct.setPostingDate(businessDate);

        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setInterestStartDate(amInterestAccrualInvestorInfo.getAccrualStartDate());
        intrAcct.setAccountingPhase(amInterestAccrualInvestorInfo.getAccountingPhase());
        intrAcct.setNonAccrualsFlag(amInterestAccrualInvestorInfo.getNonAccrualsFlag());
        intrAcct.setLoanClassify(amInterestAccrualInvestorInfo.getLoanClassify());
        intrAcct.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        intrAcct.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        intrAcct.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        intrAcct.setTaxAmt(amInterestAccrualInvestorInfo.getTaxAmt());//税金
        intrAcct.setLiabilityFlag(amInterestAccrualInvestorInfo.getLiabilityFlag());

        //添加代偿回购判断
        if(TransBizConstant.COMPENSATORY_FLAG_1.equals(amInterestAccrualInvestorInfo.getCompensatoryFlag())){
            intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_1);//代偿标识
            intrAcct.setCompensatoryDays(TransBizConstant.ONE);//	代偿天数为1
        }

        String accuTxnCode = amInterestAccrualInvestorInfo.getTxnCode();
        String acctTxnCode = accuTxnCode.substring(0,1)+(Integer.parseInt(accuTxnCode.substring(1))-10);
        intrAcct.setTxnCode(acctTxnCode);
        //利息
        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(amInterestAccrualInvestorInfo.getAccountType())) {
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_04);//账户类型
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_04, amInterestAccrualInvestorInfo.getTenantId(),
                    amInterestAccrualInvestorInfo.getCustomerId()));
            //更新订单上的余额  上层需更新订单 将更新字段入库
            loanAccountInvestorInfo.setCurrBalance(loanAccountInvestorInfo.getCurrBalance().add(intrAcct.getPostingAmount()));
            loanAccountInvestorInfo.setInterestBalance(loanAccountInvestorInfo.getInterestBalance().add(intrAcct.getPostingAmount()));
            loanAccountInvestorInfo.setAccruedInterest(BigDecimalUtils.substract(loanAccountInvestorInfo.getAccruedInterest(),intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(amInterestAccrualInvestorInfo.getPaymentDueDate());//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(amInterestAccrualInvestorInfo.getAccountType())) {//罚息
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_11);//账户类型
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_11, loanMainInvestorInfo.getTenantId(),
                    loanMainInvestorInfo.getCustomerId()));
            //更新订单上的罚息余额
            loanAccountInvestorInfo.setPenaltyBalance(loanAccountInvestorInfo.getPenaltyBalance().add(intrAcct.getPostingAmount()));
            loanAccountInvestorInfo.setAccruedPenalty(BigDecimalUtils.substract(loanAccountInvestorInfo.getAccruedPenalty(),intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(businessDate);//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_2);
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(amInterestAccrualInvestorInfo.getAccountType())) {//复利
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_12);//账户类型  复利
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_12, loanMainInvestorInfo.getTenantId(),
                    loanMainInvestorInfo.getCustomerId()));
            //更新订单上的复利余额
            loanAccountInvestorInfo.setCompoundBalance(loanAccountInvestorInfo.getCompoundBalance().add(intrAcct.getPostingAmount()));
            loanAccountInvestorInfo.setAccruedCompound(BigDecimalUtils.substract(loanAccountInvestorInfo.getAccruedCompound(),intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(businessDate);//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_2);
        }

        intrAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        intrAcct.setCreateTime(null);
        intrAcct.setUpdateTime(null);
        intrAcct.setUpdateBy(TransBizConstant.SYS_OPRATE);
        InvestorCastAccountTransactionBean castAccountTransactionBean = new InvestorCastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(intrAcct);


        //生成Gl流水
        TlGlInterfaceInvestorInfo tlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(intrAcct, intrAcct.getPostingAmount().subtract(amInterestAccrualInvestorInfo.getTaxAmt()),
                intrAcct.getTxnCode(), intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);

        //价税分离
        String tranCode = acctTxnCode.substring(0,1)+(Integer.parseInt(acctTxnCode.substring(1))+3);
        TlGlInterfaceInvestorInfo taxTlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(intrAcct, amInterestAccrualInvestorInfo.getTaxAmt(),tranCode
                , intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(taxTlGlInterfaceInfo);

        return castAccountTransactionBean;
    }

    /**
     * 根据原累计账户生成表外累计账户
     *
     * @param accuAcct
     * @param bussinessDate
     * @return
     * @throws TxnBizException
     */
    @Override
    public AmInterestAccrualInvestorInfo castNonInterestAccrualAccount(AmInterestAccrualInvestorInfo accuAcct, Date bussinessDate) throws TxnBizException {
        AmInterestAccrualInvestorInfo nonAccuAcct = new AmInterestAccrualInvestorInfo();
        BeanMapping.copy(accuAcct, nonAccuAcct);
        try {
            nonAccuAcct.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INVESTOR_INFO));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }

        String txnCode = accuAcct.getTxnCode().replaceFirst("5","9");
        nonAccuAcct.setTxnCode(txnCode);
        nonAccuAcct.setAccountId(getAccountId(accuAcct.getAccountType(),
                accuAcct.getTenantId(), accuAcct.getCustomerId()));//账户ID
        nonAccuAcct.setAccrualStartDate(bussinessDate);//交易起息日期
        nonAccuAcct.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        nonAccuAcct.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        if(TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(accuAcct.getAccountType())) {
            nonAccuAcct.setMaxInterest(accuAcct.getMaxInterest().subtract(accuAcct.getAccrualTotalAccruInterest()));//最大利息金额
        }else{
            nonAccuAcct.setMaxInterest(BigDecimal.ZERO);//最大利息金额
        }
        nonAccuAcct.setTaxAmt(BigDecimal.ZERO);
        nonAccuAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        nonAccuAcct.setCreateTime(null);
        nonAccuAcct.setUpdateTime(null);
        return nonAccuAcct;
    }

    /**
     * 生成费用轧差交易账户
     * @param offSetLoanMainInvestorInfo
     * @param offsetAmt
     * @param businessDate
     * @return
     */
    @Override
    public InvestorCastAccountTransactionBean castOffsetFeeAccount(AmLoanMainInvestorInfo offSetLoanMainInvestorInfo, AmLoanAccountInvestorInfo offsetLoanAccountInvestorInfo,BigDecimal offsetAmt, int tenor,String feeTxnCode,Date businessDate) throws TxnException {
        AmAccountMainInvestorInfo feeAccount = new AmAccountMainInvestorInfo();
        BeanMapping.copy(offSetLoanMainInvestorInfo, feeAccount);
        try {
            feeAccount.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        feeAccount.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_03, offSetLoanMainInvestorInfo.getTenantId(), offSetLoanMainInvestorInfo.getCustomerId()));//账户ID
        feeAccount.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        feeAccount.setAccountType(TransBizConstant.ACCOUNT_TYPE_03);//账户类型
        feeAccount.setBillingTenor(tenor);
        feeAccount.setTxnCode(feeTxnCode);//交易码
        feeAccount.setPostingAmount(offsetAmt);//入账金额
        feeAccount.setPostingDate(businessDate);//入账时间
        feeAccount.setRepayAmount(BigDecimal.ZERO);//已还金额
        feeAccount.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        feeAccount.setCurrBalance(offsetAmt);//余额
        feeAccount.setInterestStartDate(businessDate);//交易起息日
        feeAccount.setPaymentDueDate(businessDate);//到期还款日
        feeAccount.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        feeAccount.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        feeAccount.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        feeAccount.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        feeAccount.setLiabilityFlag(TransBizConstant.LIABILITY_FLAG_03);
        feeAccount.setTaxAmt(BigDecimal.ZERO);
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setCreateTime(null);
        feeAccount.setUpdateTime(null);
        feeAccount.setUpdateBy(TransBizConstant.SYS_OPRATE);

        //会计状态
        feeAccount.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        //应计/非应计
        feeAccount.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        //五级分类
        feeAccount.setLoanClassify(offsetLoanAccountInvestorInfo.getLoanClassify());
        //生成GL流水
        TlGlInterfaceInvestorInfo tlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(feeAccount, feeAccount.getPostingAmount(),
                feeAccount.getTxnCode(), feeAccount.getAccountingPhase(), businessDate);
        InvestorCastAccountTransactionBean castAccountTransactionBean = new InvestorCastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(feeAccount);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    /**
     * 抛出罚息、复利累计账户
     * @param plan
     * @param loanMain
     * @param loanAcct
     * @param penaltyRateTable
     * @param delqParamBean
     * @param intrBeginDate
     * @return
     * @throws TxnBizException
     */
    @Override
    public List<AmInterestAccrualInvestorInfo> castPenAndComAccrualAccount(AmRepaymentPlanInvestorInfo plan, AmLoanMainInvestorInfo loanMain, AmLoanAccountInvestorInfo loanAcct,
                                                                           PrInvestorPenaltyRate penaltyRateTable, DelqParamBean delqParamBean, Date intrBeginDate) throws TxnBizException {
        List<AmInterestAccrualInvestorInfo> accountList = new ArrayList<>();
        PrProductTable prProductTable = productTableService.findProByProIdAndOrgId(loanMain.getProductId(), loanMain.getOrganizationId(), loanMain.getTenantId());

        //计息基础
        String accrualBasic = penaltyRateTable.getAccrualBasic();

        //本金罚息计息基础
        BigDecimal accrualBaseAmount = plan.getPrincipalAmount().subtract(plan.getRepayPrincipal());
        //本金罚息累计账户
        AmInterestAccrualInvestorInfo penaltyAccrualInfo = generatePenOrComAccrualInfo(TransBizConstant.INTEREST_ACCRUAL_TYPE_10, loanMain, loanAcct,
                plan, prProductTable, penaltyRateTable, accrualBaseAmount, delqParamBean,intrBeginDate);
        if (penaltyAccrualInfo != null) {
            accountList.add(penaltyAccrualInfo);
        }
        //1:逾期本金+利息（复利）
        if (TransBizConstant.PENALTY_ACCRUAL_BASIC_1.equals(accrualBasic)) {
            //复利计息基础
            BigDecimal comAccrualBaseAmount = plan.getInterestAmount().subtract(plan.getRepayInterest());
            if(comAccrualBaseAmount.compareTo(BigDecimal.ZERO)>0) {
                //复利累计账户
                AmInterestAccrualInvestorInfo comAccrualInfo = generatePenOrComAccrualInfo(TransBizConstant.INTEREST_ACCRUAL_TYPE_20, loanMain, loanAcct,
                        plan, prProductTable, penaltyRateTable, comAccrualBaseAmount, delqParamBean, intrBeginDate);
                if (comAccrualInfo != null) {
                    accountList.add(comAccrualInfo);
                }
            }
        }
        return accountList;
    }

    /**
     * 组装罚息/复利累计账户
     * @param accountType
     * @param loanMain
     * @param loanAcct
     * @param plan
     * @param prProductTable
     * @param penaltyRateTable
     * @param accrualBaseAmount
     * @param delqParamBean
     * @param intrBeginDate
     * @return
     * @throws TxnBizException
     */
    private AmInterestAccrualInvestorInfo generatePenOrComAccrualInfo(String accountType, AmLoanMainInvestorInfo loanMain, AmLoanAccountInvestorInfo loanAcct,
                                                              AmRepaymentPlanInvestorInfo plan, PrProductTable prProductTable,
                                                              PrInvestorPenaltyRate penaltyRateTable, BigDecimal accrualBaseAmount,
                                                              DelqParamBean delqParamBean,Date intrBeginDate) throws TxnBizException {
        //起息日
        String valueDate = penaltyRateTable.getValueDate();
        Integer graceDays = prProductTable.getGraceDays();
        //按订单计算 订单级宽限期，若往期处于逾期状态，则当期没有宽限期
        if (TransBizConstant.GRACE_OPTION_BY_LOAN.equals(prProductTable.getGraceOption())
                //前一期逾期   宽限期置0
                && TransBizConstant.LOAN_STATUS_2.equals(loanAcct.getAccountStatus())) {
            graceDays = 0;
        }

        //计息开始日期
        Date accrualFromDate = null;
        //计提开始日期 交易起息日
        Date accrualStartDate = null;
        Date lastGraceDate = DateUtils.addDay(plan.getPaymentDueDate(), graceDays);
        //1:还款日起息
        if(null == intrBeginDate || intrBeginDate.compareTo(lastGraceDate) <= 0) {
            if (TransBizConstant.PENALTY_VALUE_DATE_PAYMENT_DAY.equals(valueDate)) {
                accrualFromDate = DateUtils.addDay(plan.getPaymentDueDate(), -1);
            } else if (TransBizConstant.PENALTY_VALUE_DATE_GRACE_DAY.equals(valueDate)) {//0:宽限日起息
                accrualFromDate = DateUtils.addDay(lastGraceDate,-1);
            }
            accrualStartDate = lastGraceDate;
        }else if(intrBeginDate.compareTo(lastGraceDate) >0){
            accrualFromDate = DateUtils.addDay(intrBeginDate,-1);
            accrualStartDate = intrBeginDate;
        }

        //罚息日利率
        BigDecimal dailyRate = prInvestorPenaltyRateService.getPenaltyDailyRate(loanMain.getActualDailyRate(), penaltyRateTable);

        if (accrualBaseAmount.compareTo(BigDecimal.ZERO) == 0) {
            return null;
        }
        AmInterestAccrualInvestorInfo amInterestAccrualInfo = new AmInterestAccrualInvestorInfo();
        BeanMapping.copy(loanMain, amInterestAccrualInfo);
        try {
            amInterestAccrualInfo.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INFO_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        amInterestAccrualInfo.setAccrualDailyRate(dailyRate);
        amInterestAccrualInfo.setBillingTenor(plan.getBillingTenor());
        amInterestAccrualInfo.setAccountId(getAccountId(accountType, loanMain.getTenantId(), loanMain.getCustomerId()));//账户ID
        amInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_1);//状态
        amInterestAccrualInfo.setAccountType(accountType);//类型 罚息累计账户
        amInterestAccrualInfo.setAccrualBaseAmount(accrualBaseAmount);//计息金额
        amInterestAccrualInfo.setAccrualStartDate(accrualStartDate);//交易起息日期  还款日加宽限期
        amInterestAccrualInfo.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        amInterestAccrualInfo.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        amInterestAccrualInfo.setAccrualNewFromDate(accrualFromDate);//累计利息开始日期
        amInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_0);//停止累计息标志	0 = 正常计息  1 = 停止计息
        amInterestAccrualInfo.setMaxInterest(BigDecimal.ZERO);//最大利息金额
        amInterestAccrualInfo.setProfitShared(TransBizConstant.NO_FLAG);//是否已经分润	0 = 未分润 1 = 已分润  默认为0，未分润	初始固定值：0
        amInterestAccrualInfo.setBalTransferFlag(TransBizConstant.NO_FLAG);//债权转移标识
        amInterestAccrualInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG);//代偿标识
        amInterestAccrualInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);//	记录版本号	初始固定值：1
        amInterestAccrualInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amInterestAccrualInfo.setAccrualDailyAdjustment(BigDecimal.ZERO);
        amInterestAccrualInfo.setTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setLiabilityFlag(plan.getLiabilityFlag());
        amInterestAccrualInfo.setPaymentDueDate(plan.getPaymentDueDate());
        amInterestAccrualInfo.setInterestTableId(loanMain.getInvestorInterestTableId());
        amInterestAccrualInfo.setPenaltyTableId(loanMain.getInvestorPenaltyTableId());
        amInterestAccrualInfo.setCreateTime(null);
        amInterestAccrualInfo.setUpdateTime(null);
        //会计状态
        amInterestAccrualInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_1);
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amInterestAccrualInfo, loanAcct);
        //五级分类
        amInterestAccrualInfo.setLoanClassify(loanAcct.getLoanClassify());

        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(amInterestAccrualInfo.getAccountType())) {//罚息计提
            if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_PEN_INTR_ACCU);
            } else {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_PEN_INTR_NONACCRUAL_ACCU);
            }
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(amInterestAccrualInfo.getAccountType())) {//罚息计提
            if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_COM_INTR_ACCU);
            } else {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_COM_INTR_NONACCRUAL_ACCU);
            }
        }

        return amInterestAccrualInfo;
    }

    /**
     * 交易账户应计转非应计
     *
     * @param delqParamBean 延滞参数
     * @param amAccountMainInfo 交易账户信息
     * @param amLoanAccountInfo 订单账户信息
     * @author liuyang
     * @date 2020-05-25
     */
    private void transNonAccrualsFlag(DelqParamBean delqParamBean, AmAccountMainInvestorInfo amAccountMainInfo, AmLoanAccountInvestorInfo amLoanAccountInfo) {
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(amAccountMainInfo.getAccountType());
        //不转列 或者 转列方式为当期金额转列法
        if (TransBizConstant.TRANSFER_FLAG_0.equals(delqNonAccrualBean.getNonAccrualFlag())
                || TransBizConstant.TRANSFER_METHOD_3.equals(delqNonAccrualBean.getTransferMethod())) {
            amAccountMainInfo.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
            return;
        }
        amAccountMainInfo.setNonAccrualsFlag(amLoanAccountInfo.getNonAccrualsFlag());
    }

    /**
     * 累计账户应计转非应计
     *
     * @param delqParamBean 延滞参数
     * @param amInterestAccrualInfo 累计账户信息
     * @param amLoanAccountInfo 订单账户信息
     * @author liuyang
     * @date 2020-05-25
     */
    private void transNonAccrualsFlag(DelqParamBean delqParamBean, AmInterestAccrualInvestorInfo amInterestAccrualInfo, AmLoanAccountInvestorInfo amLoanAccountInfo) {
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(amInterestAccrualInfo.getAccountType());
        //不转列 或者 转列方式为当期金额转列法
        if (TransBizConstant.TRANSFER_FLAG_0.equals(delqNonAccrualBean.getNonAccrualFlag())
                || TransBizConstant.TRANSFER_METHOD_3.equals(delqNonAccrualBean.getTransferMethod())) {
            amInterestAccrualInfo.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
            return;
        }
        amInterestAccrualInfo.setNonAccrualsFlag(amLoanAccountInfo.getNonAccrualsFlag());
    }
    /**
     * 生成延滞交易账户
     *
     * @param amLoanMainInfo 订单信息
     * @param amRepaymentPlanInfo 还款计划
     * @param businessdate 业务日期
     * @param delqDays 逾期天数
     * @return AmDelinquencyInvestorInfo 延滞交易账户
     * @throws TxnBizException
     * @author liuyang
     * @date 2020-05-21
     */
    @Override
    public AmDelinquencyInvestorInfo generateDelinquencyInfo(AmLoanMainInvestorInfo amLoanMainInfo, AmRepaymentPlanInvestorInfo amRepaymentPlanInfo, Date businessdate, Integer delqDays) throws TxnBizException {
        AmDelinquencyInvestorInfo amDelinquencyInfo = new AmDelinquencyInvestorInfo();
        BeanMapping.copy(amRepaymentPlanInfo, amDelinquencyInfo);
        try {
            amDelinquencyInfo.setId(segmentService.getId(TransBizConstant.AM_DELINQUENCY_INVESTOR_INFO));//主键id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        amDelinquencyInfo.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_50, amLoanMainInfo.getTenantId(),
                amLoanMainInfo.getCustomerId()));
        amDelinquencyInfo.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        amDelinquencyInfo.setAccountType(TransBizConstant.ACCOUNT_TYPE_50);
        amDelinquencyInfo.setDelqDate(businessdate);
        amDelinquencyInfo.setDelqDays(delqDays);
        amDelinquencyInfo.setLastDelqDays(0);
        //当期本金(principal_amount)-当前已还本金(repay_principal)+当期利息(interest_amount)-当期已还利息(repay_interest)+当期费用(fee_amount)-当期已还费用(repay_fee)
        BigDecimal totalAmountDue = amRepaymentPlanInfo.getPrincipalAmount().subtract(amRepaymentPlanInfo.getRepayPrincipal())
                .add(amRepaymentPlanInfo.getInterestAmount()).subtract(amRepaymentPlanInfo.getRepayInterest())
                .add(amRepaymentPlanInfo.getFeeAmount()).subtract(amRepaymentPlanInfo.getRepayFee());
        amDelinquencyInfo.setTotalAmountDue(totalAmountDue);
        amDelinquencyInfo.setDelqProcessTableId(amLoanMainInfo.getDelqTableId());
        amDelinquencyInfo.setPenaltyTableId(amLoanMainInfo.getInvestorPenaltyTableId());
        amDelinquencyInfo.setFundId(amLoanMainInfo.getFundId());
        amDelinquencyInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amDelinquencyInfo.setCreateTime(null); // 创建时间设置为空
        amDelinquencyInfo.setUpdateTime(null); // 更新时间设置为空
        return amDelinquencyInfo;
    }

    /**
     * 抛出提前还款／提前结清费用账户
     *
     * @param amLoanMainInfo
     * @param feeTxnCode
     * @param fee
     * @param businessDate
     * @return
     * @throws TxnBizException
     */
    @Override
    public InvestorCastAccountTransactionBean castPaymentFeeAccount(AmLoanMainInvestorInfo amLoanMainInfo, AmLoanAccountInvestorInfo amLoanAccountInfo, String feeTxnCode,
                                                                    BigDecimal fee, Date businessDate,String liabilityFlag) throws TxnException {
        AmAccountMainInvestorInfo feeAccount = new AmAccountMainInvestorInfo();
        BeanMapping.copy(amLoanMainInfo, feeAccount);
        try {
            feeAccount.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        feeAccount.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_03, amLoanMainInfo.getTenantId(), amLoanMainInfo.getCustomerId()));//账户ID
        feeAccount.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        feeAccount.setAccountType(TransBizConstant.ACCOUNT_TYPE_03);//账户类型
        feeAccount.setBillingTenor(amLoanAccountInfo.getCastTenor());
        feeAccount.setTxnCode(feeTxnCode);//交易码
        feeAccount.setPostingAmount(fee);//入账金额
        feeAccount.setPostingDate(businessDate);//入账时间
        feeAccount.setRepayAmount(BigDecimal.ZERO);//已还金额
        feeAccount.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        feeAccount.setCurrBalance(fee);//余额
        feeAccount.setInterestStartDate(businessDate);//交易起息日
        feeAccount.setPaymentDueDate(businessDate);//到期还款日
        feeAccount.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        feeAccount.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        feeAccount.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        feeAccount.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        feeAccount.setLiabilityFlag(liabilityFlag);
        feeAccount.setTaxAmt(BigDecimal.ZERO);
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setCreateTime(null);
        feeAccount.setUpdateTime(null);
        feeAccount.setUpdateBy(TransBizConstant.SYS_OPRATE);

        //会计状态
        feeAccount.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        //应计/非应计
        feeAccount.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        //五级分类
        feeAccount.setLoanClassify(amLoanAccountInfo.getLoanClassify());
        //生成GL流水
        TlGlInterfaceInvestorInfo tlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(feeAccount, feeAccount.getPostingAmount(),
                feeAccount.getTxnCode(), feeAccount.getAccountingPhase(), businessDate);
        InvestorCastAccountTransactionBean castAccountTransactionBean = new InvestorCastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(feeAccount);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    /**
     * 根据还款计划抛出利息交易账户
     *
     * @param amLoanMainInfo      订单
     * @param amRepaymentPlanInfo 当期还款计划
     * @param businessDate        业务日期
     * @return
     * @throws TxnBizException
     */
    @Override
    public InvestorCastAccountTransactionBean castIntrAccount(AmLoanMainInvestorInfo amLoanMainInfo, AmLoanAccountInvestorInfo amLoanAccountInfo,
                                                      AmRepaymentPlanInvestorInfo amRepaymentPlanInfo, DelqParamBean delqParamBean, Date businessDate) throws TxnException {
        AmAccountMainInvestorInfo intrAcct = new AmAccountMainInvestorInfo();
        BeanMapping.copy(amLoanMainInfo, intrAcct);
        try {
            intrAcct.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));//
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_04, amLoanMainInfo.getTenantId(),
                amLoanMainInfo.getCustomerId()));
        //账户ID 生成规则
        intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_04);//账户类型
        intrAcct.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR);
        intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        intrAcct.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());//期次
        intrAcct.setPostingAmount(amRepaymentPlanInfo.getInterestAmount());//入账金额
        intrAcct.setCurrBalance(amRepaymentPlanInfo.getInterestAmount());//余额
        intrAcct.setRepayAmount(BigDecimal.ZERO);//已还金额
        intrAcct.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        intrAcct.setPaymentDueDate(amRepaymentPlanInfo.getPaymentDueDate());//到期还款日
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        intrAcct.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        intrAcct.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        intrAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        intrAcct.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        intrAcct.setCreateTime(null);
        intrAcct.setUpdateTime(null);
        intrAcct.setUpdateBy(TransBizConstant.SYS_OPRATE);
        //会计状态
        intrAcct.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, intrAcct, amLoanAccountInfo);
        //五级分类
        intrAcct.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        //更新订单上的余额  上层需更新订单 将更新字段入库
        amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(intrAcct.getPostingAmount()));
        amLoanAccountInfo.setInterestBalance(amLoanAccountInfo.getInterestBalance().add(intrAcct.getPostingAmount()));


        //价税分离
        BigDecimal taxAmt = BigDecimal.ZERO;
        PrInvestorInterestRate interestRate = investorInterestRateService.findInterestByInterestId(intrAcct.getInvestorInterestTableId(), intrAcct.getOrganizationId(), intrAcct.getTenantId());
        if(TransBizConstant.TAX_FLAG_0.equals(interestRate.getTaxFlag())){
            //税金=含税收入金额/（1+税率）*税率计算每日利息的税金
            taxAmt = intrAcct.getPostingAmount().multiply(interestRate.getTaxRate()).divide(BigDecimal.ONE.add(interestRate.getTaxRate()), CommonContants.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
            intrAcct.setTaxAmt(taxAmt);
        }

        //生成GL流水
        TlGlInterfaceInvestorInfo tlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(intrAcct, intrAcct.getPostingAmount().subtract(taxAmt),
                intrAcct.getTxnCode(), intrAcct.getAccountingPhase(), businessDate);
        InvestorCastAccountTransactionBean castAccountTransactionBean = new InvestorCastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(intrAcct);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);

        TlGlInterfaceInvestorInfo taxTlGlInterfaceInfo = glInterfaceInvestorService.buildTlGlInterfaceInvestorInfo(intrAcct, taxAmt,TransBizConstant.TXN_CODE_INST_INTR_TAX
                , intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(taxTlGlInterfaceInfo);
        return castAccountTransactionBean;
    }
}
